<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Read-write Git access</title>
<link rel="stylesheet" type="text/css" href="https://gcc.gnu.org/gcc.css" />
</head>

<body>

<h1>Read-write Git access</h1>

<p>We have read/write access to the Git repository available for
maintainers and significant developers.</p>

<p>Our <a href="about.html#git">web pages are managed via git</a>.</p>

<hr />
<h2>Contents</h2>
<ol>
  <li><a href="#authenticated">Authenticated access</a></li>
  <li><a href="#setup">Setting up your local Git tree</a></li>
  <li><a href="#policies">Write access policies</a></li>
  <li><a href="#testing">Testing changes</a></li>
  <li><a href="#checkin">Checking in a change</a></li>
  <li><a href="#branches">Creating and using branches</a></li>
  <li><a href="#vendor">Personal and Vendor branches</a></li>
  <li><a href="#account">Tips&amp;Tricks around your account</a></li>
</ol>

<hr />
<h2 id="authenticated">Authenticated access</h2>

<p>We provide authenticated access via the SSH protocol.  This needs to
be sponsored by an existing maintainer (someone with "write after approval"
is not sufficient).</p>

<p>If you already have an account on sourceware.org / gcc.gnu.org, ask
<code>overseers@gcc.gnu.org</code> to add access to the GCC repository.
Include the name of your sponsor and CC: them.
Otherwise use <a
href="https://sourceware.org/cgi-bin/pdw/ps_form.cgi">this form</a>,
again specifying your sponsor.</p>

<p>We will then provision you and inform you by mail. At this point,
check out a tree using the instructions below and add yourself
to the MAINTAINERS file.  Note: Your first and last names <em>must</em>
be exactly the same between your account on gcc.gnu.org and the
MAINTAINERS file.   Place your name in the correct section following
the conventions specified in the file (e.g. "Write After Approval"
is "last name alphabetical order").  If you do not have an FSF copyright
assignment on file, also add yourself to the DCO section in the file.</p>

<p>Then produce a diff to that file and circulate it to the
<code>gcc-patches</code> list, whilst also checking in your change to
test write access (approval from the mailing list is not needed in this
one case).  For all other changes, please be sure to follow the write
access policies below.</p>

<hr />
<h2 id="setup">Setting up your local Git tree</h2>

<p>Check out the GCC sources by issuing the command:</p>

<blockquote><p><code>
git clone git+ssh://<i>username</i>@gcc.gnu.org/git/gcc.git gcc
</code></p></blockquote>

<p>where <i>username</i> is your user name at gcc.gnu.org.</p>

<p>It is also possible to convert an existing Git tree to use SSH by
using <code>git remote</code>:</p>

<blockquote><p><code>
git remote set-url origin git+ssh://<i>username</i>@gcc.gnu.org/git/gcc.git
</code></p></blockquote>

<p>To avoid the nuisance of having to supply your passphrase for each
operation, you may want to use <code>ssh-agent</code>(1) and
<code>ssh-add</code>(1).</p>

<p>To avoid messages about (lack of) X11 forwarding, put in your
<samp>$HOME/.ssh/config</samp> an entry like:</p>

<blockquote><p><code>
Host gcc.gnu.org<br />
&nbsp;&nbsp;ForwardX11 no
</code></p></blockquote>

<p>Git needs to know your name and email address.  If you have not
already configured those in <samp>$HOME/.gitconfig</samp>, do:</p>

<blockquote><p><code>
git config --global user.name "<i>Your Name</i>"<br />
git config --global user.email "<i>Your Email Address</i>"
</code></p></blockquote>

<p>If you wish to use a different name or email address for GCC
commits from that in <samp>$HOME/.gitconfig</samp>, you can configure
that in an individual Git tree using similar invocations
without <code>--global</code>.</p>

<hr />
<h2 id="policies">Write access policies</h2>

<p>The GCC project grants developers various levels of write access to
and review authority over the GCC master sources.  We have not put any
technical enforcement in place, rather we rely on everyone to follow
the appropriate policies.</p>

<dl>
  <dt>Global reviewers.</dt>
  <dd><p>A limited number of developers have global review permission
  and can approve other people's changes to any part of the compiler.
  </p></dd>

  <dt>Localized write permission.</dt>
  <dd><p>This is for people who have primary responsibility for ports,
  front ends, or other specific aspects of the compiler.  These folks
  are allowed to make changes to areas they maintain and related
  documentation, web pages, and test cases (and target conditionals)
  without approval from anyone else, and approve other people's changes
  in those areas.
  They must get approval for changes elsewhere in the compiler.</p>

  <p>Maintainers of a port maintain the relevant files in
  <code>gcc/config</code>, documentation, web pages, and test cases
  and aspects of these relevant to that port.  Port maintainers do
  not have approval rights beyond this.</p></dd>

  <dt>Localized review permission.</dt>
  <dd><p>This is similar to localized write permission, except
  that reviewers required approval for their own changes.</p></dd>

  <dt>Write after approval.</dt>
  <dd><p>This is folks that make regular contributions, but do not
  fall into one of the previous categories.  People with write
  after approval need to submit their patches to the list; once the
  patches have been approved by the appropriate maintainers the
  patches may be checked in.  The steering committee
  or a well-established GCC maintainer (including reviewers) can
  <a href="#authenticated">approve for write access</a> any person
  with GNU copyright assignment or <a href="dco.html">DCO</a> certification
  in place and known to submit good patches.</p></dd>
</dl>

<p>The list of folks with write access to the repository can be found
in the MAINTAINERS file in the GCC distribution.</p>

<p>When you have checked in a patch exactly as it has been approved,
you do not need to tell that to people -- including the approver.
People interested in when a particular patch is committed can check
Git or the <a href="https://gcc.gnu.org/ml/gcc-cvs/">gcc-cvs</a>
list.</p>

<h3 id="all">Free for all</h3>

<p>The following changes can be made by everyone with write access:</p>

<p>Obvious fixes can be committed without prior approval.  Just check
in the fix and copy it to <code>gcc-patches</code>.  A good test to
determine whether a fix is obvious: <q>will the person who objects to
my work the most be able to find a fault with my fix?</q>  If the fix
is later found to be faulty, it can always be rolled back.  We don't
want to get overly restrictive about checkin policies.</p>

<p>Similarly, no outside approval is needed to revert a patch that you
checked in.</p>

<p><a href="codingconventions.html#upstream">Importing files maintained
outside the tree from their official versions</a>.</p>

<p><a href="#branches">Creating and using a branch</a> for development,
including outside the parts of the compiler one maintains, provided that
changes on the branch have copyright assignments or <a href="dco.html">DCO</a>
certification.  Merging such developments back to the mainline still needs
approval in the usual way.</p>


<hr />
<h2 id="testing">Testing changes</h2>

<p>All changes must be tested according to the 
<a href="contribute.html#testing">instructions for testing patches</a>
before they are checked in.  If you wrote the patch yourself, you
should test it yourself, unless there is a reason why someone else
must do it for you (for instance, if you are fixing a problem on a
system you do not have access to).  If you are checking in a patch for
someone else, you only need to test it if they did not.</p>

<p>You must test exactly the change you intend to check in; it is not
good enough to have tested an earlier variant.  (Unless the only
changes from the earlier variant are formatting and comment changes;
if there are <strong>any</strong> changes to the code itself you
should re-bootstrap.)  It is a good idea to re-test patches which were
submitted a long time ago before applying them, even if nothing
appears to have changed.</p>

<p>When you post your change to <code>gcc-patches</code>, state the
canonical name(s) of the platform(s) you used for testing.</p>

<p>These rules are designed to ensure that checked-in code does not
contain bugs that prevent other people from continuing to get their
work done.  There will always be bugs, but these rules help to
minimize the amount of time where the tree does not build at
all. Repeated failure to adhere to these rules could result in the
revocation of check-in privileges by the Steering Committee.</p>

<hr />
<h2 id="checkin">Checking in a change</h2>

<p>The following is meant to provide a very quick overview of how to
check in a change.  It is not meant to be a replacement for the Git
documentation but instead a supplement.  The Git documentation is
available both as part of the Git source distribution, as well as
<a href="https://git-scm.com/doc">on the Git website</a>.</p>

<p>In all the commands listed below, you can give an explicit list of
filenames to the git command.  We recommend you list files explicitly
when performing checkins to avoid accidental checkins of local
code.</p>

<p>We prefer that each checkin be of a complete, single logical
change, which may affect multiple files.  The log message for that
checkin should be a summary line (often the subject line of the email)
followed by a blank line, then any discussion of the patch, and then
the complete ChangeLog entry for the change.  This
makes it easier to correlate changes across files, and minimizes the
time the repository is inconsistent.  If you have several unrelated
changes, you should check them in separately.</p>

<ol>
<li>Sync your sources with the master repository via "<code>git
pull</code>" before attempting a checkin; this will save you a little
time if someone else has modified the source tree since the last time
you synced your sources.</li>

<li>Apply the patch to your local tree.  On master and release branches,
ChangeLog entries will be automatically added to the corresponding ChangeLog
files based on the git commit message once a day.  See the documentation of
<a href="codingconventions.html#ChangeLogs">ChangeLog format</a>.</li>

<li>Make sure to rebuild any generated files affected by
the patch and commit them with the files explicitly modified.</li>

<li>If the patch adds any new files, such as testcases, use <code>git
add</code> to make Git aware of them.</li>

<li>We recommend using "<code>git diff HEAD</code>" after applying a
patch to a local tree.  Review the output to make sure that only the
changes you want will be checked in.  Also see
if the copyright dates need to be updated.</li>

<li>Use "<code>git commit</code>" to check in the patch; either name
the files to commit explicitly on the command line, or use <code>git
commit -a</code> to commit all modified files in the source tree (it
is still necessary to use <code>git add</code> first for any new
files).  <strong>If committing a patch for someone else,
use <code>--author "<em>Author Name</em>
&lt;<em>Author@Email.Address</em>&gt;"</code> to credit the patch to
its author.</strong>  You can enter the log message via the
"<code>-m</code>" argument to commit, or wait for the editor window to
appear and enter the log message in the editor window.  <strong>If you
use <code>git commit</code> without <code>-a</code>, and without
naming files explicitly, it will only commit files explicitly added
with <code>git add</code>, and will ignore any changes to those files
made after you called <code>git add</code> for them.</strong></li>

<li>After exiting the editor, Git will check in your
changes <strong>locally</strong>.  When your prompt returns
the <strong>local</strong> checkin is finished, but you still need to
push the changes to the shared repository; do <code>git push</code>.
A message will be sent to the gcc-cvs mailing list indicating that a
change was made.  If <code>git push</code> gives an error because
someone else has pushed their own changes to the same branch,
do <code>git pull --rebase</code> before trying <code>git push</code>
again.  A typical error in this situation looks like:

<blockquote><pre>
To git+ssh://gcc.gnu.org/git/gcc.git
 ! [rejected]                master -> master (fetch first)
error: failed to push some refs to 'git+ssh://gcc.gnu.org/git/gcc.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
</pre></blockquote>
</li>
</ol>

<hr />
<h2 id="branches">Creating and using branches</h2>

<p>Git makes it very easy and cheap to create local branches for working on
separate changes.  To switch to a new local branch starting from your current
HEAD, do</p>

<blockquote><pre>
git checkout -b $BRANCH
</pre></blockquote>

If the branch is based on GCC master, you can set it up to rebase automatically
with

<blockquote><pre>
git branch -u origin/master
git config branch.$BRANCH.rebase true
</pre></blockquote>

<p>To share a long-lived development branch publicly for collaboration with
other developers, you can use <code>git push</code> as follows:</p>

<blockquote><pre>
git push origin $BRANCH:devel/$BRANCH
</pre></blockquote>

<p>Please document such branches at the
<a href="git.html#devbranches">list of development branches</a>.
</p>

<p>Shared development branches should not rebase; instead, merge master in by
hand occasionally as needed with a normal <code>git merge master</code>.  But
DO NOT then simply merge the branch back onto master; see below.</p>

<hr />
<h2 id="merges">Merging and Rebasing</h2>

<p>Every commit in the history of GCC master must follow the testing guidelines
above; when a development branch is ready to move into master, do not do a
simple git merge and push that onto master.  Instead, invoke merge
with <code>--squash</code>:</p>

<blockquote><pre>
git merge --squash $BRANCH
</pre></blockquote>

<p>This readies a single normal commit with the effect of the merge.  If the
merge can logically be divided into a series of commits that each pass testing,
you can use git tools like <code>git reset -p</code> to break up the changes
accordingly.  It may be easier to cherry-pick some smaller changes onto master
  before doing the <code>merge --squash</code>.</p>

<p>For personal development branches that are already rebased on master you
don't need to <code>merge --squash</code> squash, but still need to make sure
the commits on the branch satisfy the above rules for commits.

<hr />
<h2 id="vendor">Personal and vendor branches</h2>

The GCC git repository is used by many people and the branch and tag
namespace would become very polluted if all branches lived at the
top-level naming space.  To help minimise the amount of data that
needs to be fetched the git repository on gcc.gnu.org supports
having personal and vendor spaces that developers use to
share their work.  These are not pulled by default, but simple
configuration steps can give access to them.

<ul>
  <li>Personal branches live
    in <code>refs/users/<i>username</i>/heads</code> with tags
    in <code>refs/users/<i>username</i>/tags</code>.</li>
  <li>Vendor branches live
    in <code>refs/vendors/<i>vendor-name</i>/heads</code> with tags
    in <code>refs/vendors/<i>vendor-name</i>/tags</code>.</li>
</ul>

<p><em>Personal and vendor spaces are controlled by the individual
user or vendor.  Do not push changes to somebody else's space without
their express permission.</em>  Rather than pushing to somebody
else's branch, consider pushing to your own personal branch and having
collaborators pull from there.
</p>

<p>Scripts exist in the contrib directory to help manage these spaces.</p>

<h3>contrib/gcc-git-customization.sh</h3>

<p>This script will help set up your personal area.  It will also define
some aliases that might be useful when developing GCC.  The script will
  first ask a number of questions:</p>
<ul>
  <li><i>Your name</i> - git uses this when you commit messages.  You
    can set this globally, but the script will confirm the setting is
    appropriate for GCC as well.  If you have not already set this
    then git will try to find your name from your account.</li>
  <li><i>Your email address</i> - similar to above.  If this is not
    set globally, the script will not attempt to guess this field, so
    you must provide a suitable answer.</li>
  <li><i>The local name for the upstream repository</i> - normally, the
    default (origin) will be correct.  This is the git remote that
    connects directly to the gcc.gnu.org server.</li>
  <li><i>Your account name on gcc.gnu.org</i> - the script will try to
    work this out based on the URL used to fetch from the git server, or
    fall back to your local user name if that fails.  Using this name
    on the server for your personal space ensures that your branches will
    not conflict with anybody else's.</li>
  <li><i>The prefix to use for your personal branches</i> - the default is
    <code>me</code>, but you can change this if you prefer.  The script
    will add configuration information to allow local branches that
    start <code>me/&lt;branch&gt;</code> to be pushed or pulled from
    your personal space in the gcc git repository on the server.
    Do not worry if you do not have an account on gcc.gnu.org.  You will
    not be able to create a personal space on the server, but other
    settings configured by the script will still be useful.</li>
</ul>

<p>If you have personal branches pushed to the gcc repository you can fetch
updates from your personal space by running
<code>git fetch users/me</code> (or whatever personal prefix you've
chosen).  You can also push an already existing branch using <code>git
push users/me me/branch</code>.  Beware that if you have more than one
personal branch set up locally, simply typing <code>git push
users/me</code> will potentially push all personal branches based on
that remote.  Use --dry-run to check that what will be pushed is what
you intend.  The script <code>contrib/git-add-user-branch.sh</code>
can be used to create a new personal branch which can be pushed and
pulled from the <i>users/me</i> remote.</p>

<p>The script also defines a few useful aliases that can be used with the
repository:</p>

<ul>
  <li><i>svn-rev</i> - Find the commit in the git repository that was
    created from a particular revision number from the SVN era.  The
    first parameter must be the revision number you wish to look up,
    an initial 'r' prefix is optional.  You can then pass other
    options that are accepted by git log to modify the format of the
    output.  Of particular use is the
    <code>--oneline</code> option to summarize the commit on a single line.
  </li>
  <li><i>gcc-descr</i> - Undocumented</li>
  <li><i>gcc-undescr</i> - Undocumented</li>
  <li><i>gcc-verify</i> - verify ChangeLog format for a particular commit</li>
  <li><i>gcc-backport</i> - run script that does <code>git cherry-pick -x</code>
      and reverts all modifications of ChangeLog files (both from index
      and conflicting files)</li>
  <li><i>gcc-mklog</i> - generate a ChangeLog template for a patch</li>
  <li><i>gcc-commit-mklog</i> - commit a git revision with a pre-filled
      ChangeLog template</li>
</ul>

<p>The final customization that the script makes is to add a diff rule so
that running <code>git diff</code> on a machine description file (a file
with the suffix <code>.md</code>) will annotate
the diff hunk headers with the name of the pattern being modified (in
much the same way as C function names are used).</p>

<h3>contrib/git-fetch-vendor.sh</h3>

<p><em>Vendor spaces are controlled by the named vendor.  Do not push
changes to that space without their express permission.</em></p>

<p>This script will set up a new 'remote' that can be used to access
the area used by a named vendor.  You need to
run <code>contrib/gcc-git-customization.sh</code> before you can use
this script.</p>


<p>The script requires one argument, the name of the vendor, and takes
one option, <code>--enable-push</code>, to enable pushes to
be made to the space.  If invoked with no arguments the script will
build a list of existing vendors from the server.</p>

<p>Once the script has been run, a new 'remote' will be configured with the
name <code>vendors/&lt;vendor&gt;</code>.  You can use this to fetch updates
to that vendor's branches.</p>

<p>To check out an existing vendor branch, you can use:</p>
<blockquote><pre>
    git checkout -b &lt;vendor&gt;/&lt;topic&gt; remotes/vendors/&lt;vendor&gt;/&lt;topic&gt;
</pre></blockquote>
<p>This will create a tracking branch that can be updated with normal git
  operations, such as <code>git pull</code>.</p>

<p>If you have set up push access, then the branch can similarly be pushed to
  using:</p>
<blockquote><pre>
    git push vendors/&lt;vendor&gt; &lt;vendor&gt;/&lt;topic&gt;
</pre></blockquote>

<p>The script can be re-run with, or without <code>--enable-push</code>
  to enable, or disable push operations.</p>

<h3>contrib/git-add-vendor-branch.sh</h3>

<p>Before this script can be used <code>contrib/git-fetch-vendor.sh</code>
  should be run to set up the vendor-specific workspace.  This applies
  even if the named vendor space does not yet exist on the server.</p>

<p>This script can be used to simplify the task of creating an initial
  vendor branch.  The script takes two arguments, the name of the branch
  to create (including the vendor name) and the start point.  For example,
  to create a <code>test</code> branch under the vendor <code>megacorp</code>
  run and starting from the most recent commit on <code>master</code>:</p>

<blockquote><pre>
    contrib/git-add-vendor-branch.sh  &lt;vendor&gt;/&lt;topic&gt; master
</pre></blockquote>

This will create the branch both locally and on the server, but will not
check the branch out locally.  You can do that afterwards with
<code>git checkout</code> or <code>git worktree</code>.

<h3>contrib/git-add-user-branch.sh</h3>

<p>before this script can be used, your personal space access should be
  set up by running <code>contrib/gcc-git-customization.sh</code>.</p>

<p>The script takes two arguments, the name of the new branch to create
  and a <i>ref</i> to create it from.  The personal prefix for the new
  branch is optional and will be automatically added if omitted.  For example,
  if your personal prefix is the default (me), then running:</p>

<blockquote><pre>
    contrib/git-add-user-branch.sh topic master
</pre></blockquote>

<p>will set up a branch called <code>topic</code> on the server and a
  local branch called <code>me/topic</code> that tracks it.  The branch
  can then be pushed using:</p>

<blockquote><pre>
    git push users/me me/topic
</pre></blockquote>

<hr />
<h2 id="account">Tips&amp;Tricks around your account</h2>

<p>Your gcc.gnu.org account also receives e-mail (and is what you
use for Bugzilla).  If you ever need to change the address e-mail to
<i>username</i>@gcc.gnu.org is forwarded to, you can easily
do so using</p>
<blockquote><pre>
ssh <i>username</i>@gcc.gnu.org email mynewaddress@example.com
</pre></blockquote>

<p>Similarly if you want to add a new SSH key to your account:</p>
<blockquote><pre>
ssh <i>username</i>@gcc.gnu.org appendkey &lt; KEYFILE
</pre></blockquote>

<p>Or replace all your SSH keys:</p>
<blockquote><pre>
ssh <i>username</i>@gcc.gnu.org replacekey &lt; KEYFILE
</pre></blockquote>

</body>
</html>
